package com.xyazm.order.statemachine.action.order.create.node;

import com.xyazm.common.enums.OrderStatusEnum;
import com.xyazm.common.utils.JsonUtil;
import com.xyazm.order.domain.builder.FullOrderData;
import com.xyazm.order.domain.entity.*;
import com.xyazm.order.domain.holder.NewOrderDataHolder;
import com.xyazm.order.enums.AmountTypeEnum;
import com.xyazm.order.enums.OrderNoTypeEnum;
import com.xyazm.order.enums.SnapshotTypeEnum;
import com.xyazm.order.manager.IOrderNoManager;
import com.xyazm.order.mapstruct.OrderApiMapstruct;
import com.xyazm.process.engine.process.ProcessContext;
import com.xyazm.process.engine.process.StandardProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 创建订单子订单构建节点
 * @author xuyou
 * @date 2023年02月04日 22:04
 */
@Component
public class CreateOrderSubBuilderNode extends StandardProcessor {

    @Autowired
    private IOrderNoManager orderNoManager;


    @Override
    protected void processInternal(ProcessContext context) {

        FullOrderData fullMasterOrderData = context.get("fullMasterOrderData");
        Integer productType = context.get("productType");

        // 1、生成子订单
        FullOrderData fullSubOrderData = addNewSubOrder(fullMasterOrderData, productType);

        // 2、封装子订单数据到NewOrderData对象中
        NewOrderDataHolder newOrderDataHolder = new NewOrderDataHolder();
        newOrderDataHolder.appendOrderData(fullSubOrderData);

        context.set("fullMasterOrderData", fullMasterOrderData);
        context.set("newOrderDataHolder", newOrderDataHolder);

    }

    /**
     * 生成子订单
     * @author xuyou
     * 2023-02-04 22:06
     * @param fullOrderData
     * @param productType
    */
    private FullOrderData addNewSubOrder(FullOrderData fullOrderData, Integer productType) {

        // 主单信息
        OrderInfoDO orderInfoDO = fullOrderData.getOrderInfoDO();
        // 主订单条目
        List<OrderItemDO> orderItemDOList = fullOrderData.getOrderItemDOList();
        // 主订单配送信息
        OrderDeliveryDetailDO orderDeliveryDetailDO = fullOrderData.getOrderDeliveryDetailDO();
        // 主订单支付信息
        List<OrderPaymentDetailDO> orderPaymentDetailDOList = fullOrderData.getOrderPaymentDetailDOList();
        // 主订单费用信息
        List<OrderAmountDO> orderAmountDOList = fullOrderData.getOrderAmountDOList();
        // 主订单费用明细
        List<OrderAmountDetailDO> orderAmountDetailDOList = fullOrderData.getOrderAmountDetailDOList();
        // 主订单状态变更日志信息
        OrderOperateLogDO orderOperateLogDO = fullOrderData.getOrderOperateLogDO();
        // 主订单快照数据
        List<OrderSnapshotDO> orderSnapshotDOList = fullOrderData.getOrderSnapshotDOList();


        // 父订单号
        String orderId = orderInfoDO.getOrderId();
        // 用户ID
        String userId = orderInfoDO.getUserId();
        // 生成新的子订单的订单号
        String subOrderId = orderNoManager.genOrderId(OrderNoTypeEnum.ORDER_SALE.getCode(), userId);

        // 子订单全量的数据
        FullOrderData subFullOrderData = new FullOrderData();

        // 过滤出当前商品类型的订单条目信息
        List<OrderItemDO> subOrderItemDOList = orderItemDOList.stream()
                .filter(orderItemDO -> productType.equals(orderItemDO.getProductType()))
                .collect(Collectors.toList());

        // 统计子单总金额
        // 当前商品支付原总价
        Integer subTotalAmount = 0;
        // 交易支付金额
        Integer subRealPayAmount = 0;
        for (OrderItemDO subOrderItemDO : subOrderItemDOList) {
            subTotalAmount += subOrderItemDO.getOriginAmount();
            subRealPayAmount += subOrderItemDO.getPayAmount();
        }

        // 订单主信息
        OrderInfoDO newSubOrderInfoDO = OrderApiMapstruct.INSTANCE.convertOrderInfo(orderInfoDO);
        newSubOrderInfoDO.setId(null);
        newSubOrderInfoDO.setOrderId(subOrderId);
        newSubOrderInfoDO.setParentOrderId(orderId);
        // 订单状态:无效订单
        newSubOrderInfoDO.setOrderStatus(OrderStatusEnum.INVALID.getCode());
        // 交易总金额
        newSubOrderInfoDO.setTotalAmount(subTotalAmount);
        // 交易支付金额
        newSubOrderInfoDO.setPayAmount(subRealPayAmount);
        subFullOrderData.setOrderInfoDO(newSubOrderInfoDO);

        // 订单条目
        List<OrderItemDO> newSubOrderItemDOList = new ArrayList<>();
        for (OrderItemDO orderItemDO : subOrderItemDOList) {
            OrderItemDO newSubOrderItemDO = OrderApiMapstruct.INSTANCE.convertOrderItem(orderItemDO);
            newSubOrderItemDO.setId(null);
            newSubOrderItemDO.setOrderId(subOrderId);
            // 获取子订单的orderItemId值
            String subOrderItemId = getSubOrderItemId(orderItemDO.getOrderItemId(), subOrderId);
            newSubOrderItemDO.setOrderItemId(subOrderItemId);
            newSubOrderItemDOList.add(newSubOrderItemDO);
        }
        subFullOrderData.setOrderItemDOList(newSubOrderItemDOList);

        // 订单配送地址信息
        OrderDeliveryDetailDO newSubOrderDeliveryDetailDO =
                OrderApiMapstruct.INSTANCE.convertOrderDeliveryDetail(orderDeliveryDetailDO);
        newSubOrderDeliveryDetailDO.setId(null);
        newSubOrderDeliveryDetailDO.setOrderId(subOrderId);
        subFullOrderData.setOrderDeliveryDetailDO(newSubOrderDeliveryDetailDO);

        // key:订单条目id,value:订单条目信息
        Map<String, OrderItemDO> subOrderItemMap = subOrderItemDOList.stream()
                .collect(Collectors.toMap(OrderItemDO::getOrderItemId, Function.identity()));

        // 统计子订单费用信息
        // 订单支付原价
        Integer subTotalOriginPayAmount = 0;
        // 优惠券抵扣金额
        Integer subTotalCouponDiscountAmount = 0;
        // 实付金额
        Integer subTotalRealPayAmount = 0;

        // 订单费用明细
        List<OrderAmountDetailDO> subOrderAmountDetailDOList = new ArrayList<>();
        for (OrderAmountDetailDO orderAmountDetailDO : orderAmountDetailDOList) {
            String orderItemId = orderAmountDetailDO.getOrderItemId();
            if (!subOrderItemMap.containsKey(orderItemId)) {
                continue;
            }
            OrderAmountDetailDO subOrderAmountDetailDO =
                    OrderApiMapstruct.INSTANCE.convertOrderAmountDetail(orderAmountDetailDO);
            subOrderAmountDetailDO.setId(null);
            subOrderAmountDetailDO.setOrderId(subOrderId);
            String subOrderItemId = getSubOrderItemId(orderItemId, subOrderId);
            subOrderAmountDetailDO.setOrderItemId(subOrderItemId);
            subOrderAmountDetailDOList.add(subOrderAmountDetailDO);

            Integer amountType = orderAmountDetailDO.getAmountType();
            Integer amount = orderAmountDetailDO.getAmount();
            // 累计订单支付原价
            if (AmountTypeEnum.ORIGIN_PAY_AMOUNT.getCode().equals(amountType)) {
                subTotalOriginPayAmount += amount;
            }
            // 累计优惠券抵扣金额
            if (AmountTypeEnum.COUPON_DISCOUNT_AMOUNT.getCode().equals(amountType)) {
                subTotalCouponDiscountAmount += amount;
            }
            // 累计实付金额
            if (AmountTypeEnum.REAL_PAY_AMOUNT.getCode().equals(amountType)) {
                subTotalRealPayAmount += amount;
            }
        }
        subFullOrderData.setOrderAmountDetailDOList(subOrderAmountDetailDOList);

        // 订单费用信息
        List<OrderAmountDO> subOrderAmountDOList = new ArrayList<>();
        for (OrderAmountDO orderAmountDO : orderAmountDOList) {
            Integer amountType = orderAmountDO.getAmountType();
            OrderAmountDO subOrderAmountDO = OrderApiMapstruct.INSTANCE.convertOrderAmount(orderAmountDO);
            subOrderAmountDO.setId(null);
            subOrderAmountDO.setOrderId(subOrderId);
            // 订单支付原价
            if (AmountTypeEnum.ORIGIN_PAY_AMOUNT.getCode().equals(amountType)) {
                subOrderAmountDO.setAmount(subTotalOriginPayAmount);
                subOrderAmountDOList.add(subOrderAmountDO);
            }
            // 优惠券抵扣金额
            if (AmountTypeEnum.COUPON_DISCOUNT_AMOUNT.getCode().equals(amountType)) {
                subOrderAmountDO.setAmount(subTotalCouponDiscountAmount);
                subOrderAmountDOList.add(subOrderAmountDO);
            }
            // 实付金额
            if (AmountTypeEnum.REAL_PAY_AMOUNT.getCode().equals(amountType)) {
                subOrderAmountDO.setAmount(subTotalRealPayAmount);
                subOrderAmountDOList.add(subOrderAmountDO);
            }
        }
        subFullOrderData.setOrderAmountDOList(subOrderAmountDOList);

        // 订单支付信息
        List<OrderPaymentDetailDO> subOrderPaymentDetailDOList = new ArrayList<>();
        for (OrderPaymentDetailDO orderPaymentDetailDO : orderPaymentDetailDOList) {
            OrderPaymentDetailDO subOrderPaymentDetailDO =
                    OrderApiMapstruct.INSTANCE.convertOrderPaymentDetail(orderPaymentDetailDO);
            subOrderPaymentDetailDO.setId(null);
            subOrderPaymentDetailDO.setOrderId(subOrderId);
            // 累计实付金额
            subOrderPaymentDetailDO.setPayAmount(subTotalRealPayAmount);
            subOrderPaymentDetailDOList.add(subOrderPaymentDetailDO);
        }
        subFullOrderData.setOrderPaymentDetailDOList(subOrderPaymentDetailDOList);

        // 订单状态变更日志信息
        OrderOperateLogDO subOrderOperateLogDO = OrderApiMapstruct.INSTANCE.convertOrderOperateLog(orderOperateLogDO);
        subOrderOperateLogDO.setId(null);
        subOrderOperateLogDO.setOrderId(subOrderId);
        // 当前状态 - 无效订单
        subOrderOperateLogDO.setCurrentStatus(OrderStatusEnum.INVALID.getCode());
        subOrderOperateLogDO.setRemark("创建订单操作0-127");
        subFullOrderData.setOrderOperateLogDO(subOrderOperateLogDO);

        // 订单商品快照信息
        List<OrderSnapshotDO> subOrderSnapshotDOList = new ArrayList<>();
        for (OrderSnapshotDO orderSnapshotDO : orderSnapshotDOList) {
            OrderSnapshotDO subOrderSnapshotDO = OrderApiMapstruct.INSTANCE.convertOrderSnapshot(orderSnapshotDO);
            subOrderSnapshotDO.setId(null);
            subOrderSnapshotDO.setOrderId(subOrderId);
            if (SnapshotTypeEnum.ORDER_AMOUNT.getCode().equals(orderSnapshotDO.getSnapshotType())) {
                // 订单费用信息
                subOrderSnapshotDO.setSnapshotJson(JsonUtil.object2Json(subOrderAmountDOList));
            } else if (SnapshotTypeEnum.ORDER_ITEM.getCode().equals(orderSnapshotDO.getSnapshotType())) {
                // 订单明细信息
                subOrderSnapshotDO.setSnapshotJson(JsonUtil.object2Json(subOrderItemDOList));
            }
            subOrderSnapshotDOList.add(subOrderSnapshotDO);
        }
        subFullOrderData.setOrderSnapshotDOList(subOrderSnapshotDOList);
        return subFullOrderData;
    }

    /**
     * 获取子订单的orderItemId值
     */
    private String getSubOrderItemId(String orderItemId, String subOrderId) {
        String postfix = orderItemId.substring(orderItemId.indexOf("_"));
        return subOrderId + postfix;
    }
}
